/*
 *  usmap.js
 * 
 *  This file has these main responsibilities:
 *  1. Initialize the main page, index.html.
 *  2. Setup all the listners for the main page.  
 *  3. Grab values of HTML elements for other parts of the application.
 * 
 *  @author Tanya L. Crenshaw
 */

/* From JavaScript patterns by S. Stefanov,
 *    "As the complexity of a program grows and some parts of the code
 * get split into different files, it becomes unsafe to just assume that
 * your code is first.  Therefore, before adding a property or creating
 * a namespace, it's best to check first that it doesn't already exist"
 */
var cs441GoogleMapsViz = cs441GoogleMapsViz || {};

/*
 * cs441GoogleMapsViz.getZip()
 *
 * This function gets the zipcode from the page, as entered by
 * the user in the input textbox with id "zipcode".
 *
 * @param void
 * @return The value of the html element with id "zipcode"
 */
cs441GoogleMapsViz.getZip = function() {
    var zipCodes = $("#zipcode").val().split(/(?:,| )+/);
    return zipCodes;
};
/*
 * cs441GoogleMapsViz.getRegion()
 *
 * This function gets the region from the page, as entered by
 * the user in the select input element with id "regionFilterMenu."
 *
 * @param void
 * @return The value of the html element with id "regionFilterMenu"
 */
cs441GoogleMapsViz.getRegion = function() {
    return $("#state").val();
};

/*
 *  cs441GoogleMapsViz.lookup()
 *
 *  For an array of layers, this function filters the layers
 *  according to the zipcode grabbed from the page (that is,
 * 	entered by the user) and recenters the layer's map at the zipcode.
 *
 *  This function assumes that all the layers are on the same map.
 *  Thus, when resetting the zoom and recentering the map, these
 *  operations are done only once on the first layer.
 *
 *  @param layerArray An array of Google FusionTableLayers.
 *  @param geocoder The geocoder service to use to recenter the map.
 *  @return void
 */
cs441GoogleMapsViz.lookup = function(layerArray, geocoder) {

    // Get the zip code from the page, as entered by the user.
    var zips = cs441GoogleMapsViz.getZip();

    // Filter each layer by the zip.
    cs441GoogleMapsViz.forEach(layerArray, function(t) {
        for(var i = 0; i < zips.length; ++i){
	    cs441GoogleMapsViz.filterByZip.call(t, zips[ i]);
	}
    });
    
    // Set the zoom.
    layerArray[0].map.setZoom(11);

    // Center the map.
    centerAt(layerArray[0].map, zips[0], geocoder);
}
/*
 *  cs441GoogleMapsViz.toggle()
 *
 *  @param layerArray An array of Layer objects to toggle.
 *  @return void
 */
cs441GoogleMapsViz.toggle = function(layerArray) {

    // Get the zip code from the page, as entered by the user.
    var zips = cs441GoogleMapsViz.getZip();

    // Toggle each layer by the zip.
    cs441GoogleMapsViz.forEach(layerArray, function(t) {
	for(var i = 0; i < zips.legnth; ++i){
	    cs441GoogleMapsViz.toggleLayer.call(t, zips[0]);
	}
    });
}
/*
 *  cs441GoogleMapsViz.regionalize()
 * 
 *  This function filters an array of layer objects based on the
 *  region name grabbed from the page (that is, entered by the user)
 *  and recenters the map at the region.
 *
 *  @param layerArray An array of Layer objects to regionalize.
 *  @param geocoder The geocoder service to use to recenter the map.
 *  @return void
 */
cs441GoogleMapsViz.regionalize = function(layerArray, geocoder) {

    // Get the region name from the page, as entered by the user.
    var region = cs441GoogleMapsViz.getRegion();
    
    // Filter each layer by the region.
    cs441GoogleMapsViz.forEach(layerArray, function(t) {
	cs441GoogleMapsViz.filterByRegion.call(t, region);
    });
    
    // Set the zoom.
    layerArray[0].map.setZoom(6);
    
    // Center the map at the state corresponding to the region.
    centerAt(layerArray[0].map, cs441GoogleMapsViz.convertRegionToState(region), geocoder);
}

cs441GoogleMapsViz.setStudentLayer = function (studentLayer) {
    var filter = createFilter();
    //    alert(filter);
    //apply the new filter to the student layer.
    studentLayer.ref.setOptions({
	query : {
	    from : studentLayer.getEID(),
	    where: filter
	},
	map : studentLayer.map
    });
}




/*
 *  cs441GoogleMapsViz.initialize()
 *
 *  A function to: 1. create a google map centered at the us and
 *  2: instantiate a google maps geocoder service.  Note that the
 *  variables geocoder and map are not declared using var -- this
 *  is so that they can be written to the window object and used by
 *  other functions.
 *
 *  @param void
 *  @return void
 */
cs441GoogleMapsViz.initialize = function() {
    
    // Encrypted IDs for the two layers

    // The Encrypted ID used below is that of tl_2010_41_zcta051_clean.kml
    // available in Tanya Crenshaw's public fusion tables.
    var zipEID = '1U6n-9O6I9q4qG10uNcNrCAlvactfL7O07IVPLbU';

    // The Encrypted ID used below is that of
    // OregonHighSchools_withManualFusionTableFixes.csv available
    // in Tanya Crenshaw's public fusion tables.
    var schoolEID = '1YcgR53xYb2OQm77NNyYfMh7-nwkrtZxoig7U_ms';

    // The Encrypted ID used below is that of the student csv available
    // from Tanya Crenshaw
    var studentEID = cs441GoogleMapsViz.tables["students"]["Set1"];
    cs441GoogleMapsViz.studentEID = cs441GoogleMapsViz.tables["students"]["Set1"];

    
    // Instatiate a new geocoder service
    var geocoder = new google.maps.Geocoder();
    cs441GoogleMapsViz.geocoder = geocoder;
    // The center point of the map is Lincoln, NB.
    var usa = new google.maps.LatLng(40.8358, -96.6452);

    // Create a Google Map object centered at usa
    var map = new google.maps.Map(document.getElementById("contig_us_map_canvas"), {
	zoom : 4,
	center : usa,
	mapTypeId : google.maps.MapTypeId.ROADMAP
    });
    cs441GoogleMapsViz.map = map;
    var layerArray = new Array();
    //	Constructing the layers
    //
    // Create a Layer object for the zip code boundary layer.  The first parameter
    // creates the Google FusionTablesLayer object.  The Layer is not currently being
    // filtered, so the final parameter is false.
    var zipLayer = new cs441GoogleMapsViz.Layer("zips", new google.maps.FusionTablesLayer({
	query : {
	    from : zipEID
	},
	/*styles: [{
	    polygonOptions: {
		fillColor: "#777777",
		fillOpacity: 0.0,
		strokeColor: "#444444",
		strokeWeight: "1"
	    },
	}]*/
    }), zipEID, map, 'ZipCodeArea', false);
    layerArray.push(zipLayer);

    // Create a Layer object for the high schools layer.  The first parameter
    // creates the Google FusionTablesLayer object.  The Layer is not currently being
    // filtered, so the final parameter is false.
    var schoolLayer = new cs441GoogleMapsViz.Layer("schools", new google.maps.FusionTablesLayer({
        query : {
	    from : schoolEID
	},
 	styles: [{
	    markerOptions: {
		iconName: "schools"
	    }
	}]
    }), schoolEID, map, 'Zip', false);

    layerArray.push(schoolLayer);

    var studentLayer =  new cs441GoogleMapsViz.Layer("students", new google.maps.FusionTablesLayer({
	query : {
	    from : studentEID,
	}
    }), studentEID, map, 'Zip', false);

    layerArray.push(studentLayer);
    
    cs441GoogleMapsViz.studentLayer = studentLayer;
    
    google.maps.event.addListener(studentLayer.ref, 'click', function(displayedArea) {
	var major = cs441GoogleMapsViz.collegeMajors[parseInt(displayedArea.row['Planned_Major_Code'].value,10)] || displayedArea.row['Planned_Major_Code'].value;
	displayedArea.infoWindowHtml = "<strong>ID:</strong> " + 
	    displayedArea.row['UPortland_UniqueID'].value+"<br />" +
	    "<strong>Gender: </strong>" + displayedArea.row['Gender'].value+"<br />" +
	    "<strong>Entry Year: </strong>" + displayedArea.row['Entry_Year'].value+"<br />" +
	    "<strong>Planned Major: </strong>" + major +"<br />" +
	    "<strong>GPA: </strong>" + displayedArea.row['HS_GPA'].value+"<br />" +
	    "<strong>SAT Math: </strong>" + displayedArea.row['SAT_MAth'].value+"<br >" +
	    "<strong>SAT Verbal</strong>: " + displayedArea.row['SAT_Verbal'].value+"<br >";
	
    });

    // Add a listener to the layer.  When the user clicks on the
    // particular zip code area in the layer, some information
    // about the particular zip code is displayed in the info portion
    // of the page.
    google.maps.event.addListener(zipLayer.ref, 'click', function(displayedArea) {
	
	// Get the necessary information from the clicked area
	var information = displayedArea.row['ZipCodeArea'].value + "<br />";

	// Format and display it in the information window for the displayed area.
	displayedArea.infoWindowHtml = information;
	
    });
    
    dropDownListener();
    dropDownListener2();

    var validator = new cs441GoogleMapsViz.Validator();
    // Attach the function lookup() to the lookupButton on the main page.
    cs441GoogleMapsViz.addEvent(document.getElementById('lookupButton'), 'click', function() {

	validator.validateFields();
	
 	//toggle layers on or off
	if ($("#radio-school").is(":checked")){
	    highSchoolSummary();
            layerArray[1].map = map; //school layer
            layerArray[2].map = null; //student layer
        }
	else
        {
	    studentSummary();
            layerArray[1].map = null;
            layerArray[2].map = map;
	}
	if ($("#radio-zip").is(":checked")){
	    cs441GoogleMapsViz.lookup(layerArray, geocoder);
	}
	else {
	    cs441GoogleMapsViz.regionalize(layerArray, geocoder);
	}

    });
    
}

// Setup an event listener to execute the init() function for this namespace
// upon page load.
google.maps.event.addDomListener(window, 'load', cs441GoogleMapsViz.initialize);
